package nspel

import (
	"bytes"
	"encoding/gob"
	"github.com/gomodule/redigo/redis"
	"strconv"
)

var redisPool *redis.Pool
var redisDefaultLift int

func configRedis() {
	var data = struct {
		Host     string `json:"host"`
		Port     int    `json:"port"`
		Password string `json:"password"`
		Db       int    `json:"db"`
		MaxIdle  int    `json:"maxIdle"`
		MaxOpen  int    `json:"maxOpen"`
		LifeTime int    `json:"lifeTime"`
	}{}
	loadConfigJson("config/redis.json", &data)
	redisPool = &redis.Pool{
		MaxIdle:   data.MaxIdle,
		MaxActive: data.MaxOpen,
		Dial: func() (redis.Conn, error) {
			c, err := redis.Dial("tcp", data.Host+":"+strconv.Itoa(data.Port), redis.DialPassword(data.Password), redis.DialDatabase(data.Db))
			if err != nil {
				return nil, err
			}
			return c, nil
		},
	}
	redisDefaultLift = data.LifeTime
}

func RedisGetGob(key string, object interface{}) (err error) {
	redisConnection := getRedis()
	result, err := redis.Bytes(redisConnection.Do("GET", key))
	if err != nil {
		redisConnection.Close()
		return err
	}
	var buffer bytes.Buffer
	buffer.Write(result)
	dec := gob.NewDecoder(&buffer)
	err = dec.Decode(object)
	redisConnection.Close()
	return
}

func RedisGetInt64(key string, integer *int64) (err error) {
	redisConnection := getRedis()
	*integer, err = redis.Int64(redisConnection.Do("GET", key))
	if err != nil {
		redisConnection.Close()
		return err
	}
	redisConnection.Close()
	return
}

func RedisIsExist(key string) (ok bool, err error) {
	redisConnection := getRedis()
	ok, err = redis.Bool(redisConnection.Do("EXISTS", key))
	redisConnection.Close()
	return
}

func RedisSetGob(key string, object interface{}) {
	redisConnection := getRedis()
	var buffer bytes.Buffer
	enc := gob.NewEncoder(&buffer)
	err := enc.Encode(object)
	if err != nil {
		Error(err)
		redisConnection.Close()
		return
	}
	_, err = redisConnection.Do("SET", key, buffer.Bytes(), "EX", redisDefaultLift)
	if err != nil {
		Error(err)
	}
	redisConnection.Close()
}

func RedisSetInt64(key string, interger int64) {
	redisConnection := getRedis()
	_, err := redisConnection.Do("SET", key, interger, "EX", redisDefaultLift)
	if err != nil {
		Error(err)
	}
	redisConnection.Close()
	return
}

func RedisSet(key string, value interface{}, time int64) (err error) {
	redisConnection := getRedis()
	_, err = redisConnection.Do("SET", key, value, "EX", time)
	redisConnection.Close()
	return
}

func RedisKeysDelete(keys ...string) (err error) {
	redisConnection := getRedis()
	for i := 0; i < len(keys); i++ {
		_, err = redisConnection.Do("DEL", keys[i])
		if err != nil {
			Error(err)
		}
	}
	redisConnection.Close()
	return
}

func getRedis() redis.Conn {
	return redisPool.Get()
}
